#include "mqtt.h"
#include "print.h"

void MqttClient::pinOn(const char* data, unsigned int length) {
    auto iter = pinmap.find(data);
    if (iter != pinmap.end()) {
        auto cfg = iter->second;
        if (cfg != nullptr) {
            pinOnOff(cfg, true);
        }
    }
}

void MqttClient::pinOff(const char* data, unsigned int length) {
    auto iter = pinmap.find(data);
    if (iter != pinmap.end()) {
        auto cfg = iter->second;
        if (cfg != nullptr) {
            pinOnOff(cfg, false);
        }
    }
}

void MqttClient::pinOnOff(portcfg* cfg, bool state) {
    if (cfg != nullptr && cfg->onoff != state) {
        if (state == true) {
            digitalWrite(cfg->port, HIGH);
        } else {
            digitalWrite(cfg->port, LOW);
        }
        cfg->onoff = state;
        println("pin: ", cfg->port, ", key: ", cfg->name, state ? " on" : " off");
    }
}

void MqttClient::pinState(const char* data, unsigned int length) {
    println("pin state sync, data: ", data, ", length: ", length);

    syncState = false;
    unsigned int pos = 0, posk = 0, posv = 0;
    char ch = 0, val = 0;
    char key[11] = { 0 };

    while (pos < length) {
        ch = *(data + pos++);
        if (ch == ':') {
            posk = pos;
            if (posk < posv || posk - pos > 10) {
                println("pin state sync, key out of range 10, ", data + posv);
                break;
            }
            strncpy(key, data + posv, posk - posv - 1);
            key[posk - posv] = 0;
        }
        if (ch == ',') {
            auto iter = pinmap.find(key);
            if (iter != pinmap.end() && pos - posk == 2) {
                val = *(data + posk);
                auto cfg = iter->second;
                if (cfg != nullptr && ((val == '0' && cfg->onoff == true) || val == '1' && cfg->onoff == false)) {
                    pinOnOff(cfg, !cfg->onoff);
                }
            }
            posv = pos;
        }
    }
}
